/**
 * @author Mohamed Samir
 * @version 1.0
 */
package storageManagers;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;

import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlDocument;
import com.sleepycat.dbxml.XmlEventReader;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlInputStream;
import com.sleepycat.dbxml.XmlManager;
import com.sleepycat.dbxml.XmlManagerConfig;
import com.sleepycat.dbxml.XmlQueryContext;
import com.sleepycat.dbxml.XmlQueryExpression;
import com.sleepycat.dbxml.XmlResults;
import com.sleepycat.dbxml.XmlValue;

import data.KeywordVector;

public class VectorsManager {
	//Members - Attributes
	private XmlManager myManager = null;
	private XmlContainer myContainer = null;
	private XmlManagerConfig managerConfig=null;
	private ArrayList<KeywordVector> listOfVectors=null;
	
	//-----------------------init the container and the xml manager --------------------------
	/**
	 * This method make the initializaton step by creating the manager and manager configration
	 */
	public void initialize() {
		managerConfig=new XmlManagerConfig();
		managerConfig.setAllowExternalAccess(true);
		try {
			myManager = new XmlManager(managerConfig);

			myManager.setDefaultContainerType(XmlContainer.NodeContainer);
			
		} catch (XmlException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	//------------------------------------- load posts to the container --------------------------
	//This method loads the posts XML file into the created container in the specified path
	/**
	 * @param directory The path of the folder to load the XML files from. 
	 * This method loads the vectors XML file into the created container in the specified path.
	 */
	public void  loadVectors(String directory) {
		try
		{	
		// Assumes the container currently exists.
		myContainer =myManager.createContainer("vectors.bdbxml");
		addDocs(directory);
		
		}
		catch (Exception e) {
			System.err.println("E1 "+e.getMessage());
			} finally {
			try {
			if (myContainer != null) {
			myContainer.close();
			}
			if (myManager != null) {
			myManager.close();
			}
			} catch (XmlException ce) {
			// Exception handling goes here
				System.err.println("E2 "+ce.getMessage());
			}
			}
	}

	//-------------------------------------add xml file to the container from this dir-----------------------------------
	/**
	 * add XML file to the container from this dir
	 * @param dir The directory of the XML vectors
	 */
	private void  addDocs(String dir) throws XmlException{
		XmlInputStream theStream ;
		   File folder = new File(dir);
		    File[] listOfFiles = folder.listFiles();
		    for (int i = 0; i < listOfFiles.length; i++) {
		      if (listOfFiles[i].isFile()) {
		    	  System.out.println("adding the file ... to "+ dir+listOfFiles[i].getName());
		    	   theStream =myManager.createLocalFileInputStream(dir+listOfFiles[i].getName());
					myContainer.putDocument(listOfFiles[i].getName(), theStream);
					System.out.println("v"+i +" added");
		      }
		      
		    }
	}
	


//------------------------------------- Read Posts-----------------------------------
/**
 * This function reads posts from the posts container and then build post objects and 
 * send them to the text mining phase
 * 	@return Arraylist of posts as Vector object	
 */

public ArrayList<KeywordVector> readVectors(){

	try {
		listOfVectors=new ArrayList<KeywordVector>();
		// Assumes the container currently exists.
		myContainer =myManager.openContainer("vectors.bdbxml");
		// Get a query context
		XmlQueryContext context = myManager.createQueryContext();
		String myQuery ="collection('vectors.bdbxml')/vector";
		
		XmlQueryExpression qe = myManager.prepare(myQuery, context);
		XmlResults results = qe.execute(context);
		
		String message = "Found ";
		message += results.size() + " documents for query: '";
		message += myQuery + "'\n";
		XmlValue value = results.next();
		
		while (value != null) {
		XmlDocument theDoc = value.asDocument();
		message = "Document ";
		message += theDoc.getName() + ":\n";
		message += value.asString();
		message += "\n===============================\n";
		//System.out.println(message);
		
		buidAddVector(theDoc);
		
		value = results.next();
		
		}
		
		results.delete();
		qe.delete();
				
		} catch (Exception e) {
			System.err.println(">> err here");
			System.err.println(e.getMessage());
		// Exception handling goes here
		} finally {
		try {
		if (myContainer != null) {
		myContainer.close();
		}
		if (myManager != null) {
			myManager.close();
			}
			} catch (XmlException ce) {
			// Exception handling goes here
			}
	}

		return listOfVectors;
}




//--------------------This method get the xml doc and build Vector object from it.--------------------
	/**
	 * This method takes the XML document which represent One vector XML result from the vectors container, and
	 * then parse it to make a new vector object to be ready to be sent later.
	 * @param tdoc One vector XML result from the vectors container
	 * 
	 */
	private void  buidAddVector(XmlDocument tdoc) throws XmlException{
		KeywordVector tmp=new KeywordVector();
		XmlEventReader reader = tdoc.getContentAsEventReader();
		// Now iterate over the document elements, examining only
		// those of interest to us:
		while (reader.hasNext()) {
		int type = reader.next();
		if (type == XmlEventReader.StartElement) {
			//System.out.println(reader.getLocalName()+":");

			if(reader.getLocalName().equals("vector")){
				for (int i = 0; i < reader.getAttributeCount(); i++) {
					if(reader.getAttributeLocalName(i).equals("id"))
					{
						tmp.setVectorID(Long.parseLong(reader.getAttributeValue(i)));
					}	
				}
			}
			
		else {
			String item="";
			for (int i = 0; i < reader.getAttributeCount(); i++) {
				if(reader.getAttributeLocalName(i).equals("name"))
				{
					item=reader.getAttributeValue(i);
				}	
			}
				reader.next();
				Double data=Double.parseDouble(reader.getValue());
				tmp.getData().put(item,data);
			
		}			
			//System.out.println(da+"\n ===============================");		
		}
		}
		listOfVectors.add(tmp);
		// When we are done, we close the reader to free-up resources.
		reader.close();
	
	}
	
	
}

